home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
351-375
/
disk_351
/
pdc
/
libsrc.lzh
/
LibSrc
/
StdIO
/
bufmgt.c
next >
Wrap
C/C++ Source or Header
|
1990-04-07
|
4KB
|
185 lines
/*
* Libraries and headers for PDC release 3.3 (C) 1989 Lionel Hummel.
* PDC Software Distribution (C) 1989 Lionel Hummel and Paul Petersen.
* PDC I/O Library (C) 1987 by J.A. Lydiatt.
*
* This code is freely redistributable upon the conditions that this
* notice remains intact and that modified versions of this file not
* be included as part of the PDC Software Distribution without the
* express consent of the copyright holders. No warrantee of any
* kind is provided with this code. For further information, contact:
*
* PDC Software Distribution Internet: BIX:
* P.O. Box 4006 or hummel@cs.uiuc.edu lhummel
* Urbana, IL 61801-8801 petersen@uicsrd.csrd.uiuc.edu
*/
/* bufmgt.c
*
* Performs buffer management for PDC's stdio facilities
*/
#include <stdio.h>
extern void (*_fcloseall)(), free();
extern int fclose();
extern int read(), write();
/* Our internal routine to close all buffered I/O
*/
static void fcloseall()
{
FILE *fp, *fp2;
for ( fp = (FILE *) &_fdevtab[0]; fp != NULL; fp = fp2 ) {
fp2 = fp->next;
fclose( fp );
}
}
FILE *addStream()
{
FILE *fp, *fp1;
extern char *malloc();
/* If we're going to open a stream, there should be a routine to
* close it before the program exits. If there isn't one already,
* provide our own.
*/
if (!_fcloseall)
_fcloseall = &fcloseall;
/*
* Try to nab an unused buffer
*/
fp = (FILE *) &_fdevtab[0];
while( fp != 0L ) {
fp1 = fp;
if ( !fp->_fileflag )
break;
fp = fp->next;
}
/*
* If fp is null, then there isn't an empty buffer - make one
* and link it into the chain.
*/
if ( fp == NULL ) {
fp = (FILE *) malloc(sizeof(FILE));
if ( fp == NULL )
return NULL;
fp1->next = fp;
fp->next = NULL;
}
fp->_filecpos = NULL;
fp->_fileend = NULL;
fp->_filebufp = NULL;
fp->_fileflag = 0;
return fp;
}
/* Allocate a buffer to use with the given I/O stream:
*/
addStreamBuf( fp )
FILE *fp;
{
char *buffer;
extern char *malloc();
if ( !(fp->_filebufp = malloc(BUFSIZ)) ) {
fp->_filebufp = &fp->_filebyte;
fp->_filelen = 1;
} else {
fp->_fileflag |= _FILEISDYNA;
fp->_filelen = BUFSIZ;
}
if ( isatty((int)fp->_fileunit) )
fp->_fileflag |= _FILEISTTY;
return;
}
int _filebfill( fp )
FILE *fp;
{
FILE *fp2;
int len;
if ( fp->_fileflag & (_FILEATEOF | _FILEBAD ) )
return EOF;
fp->_fileflag &= ~_FILEISDIRTY;
if ( fp->_filebufp == NULL )
addStreamBuf( fp );
if ( fp->_fileflag & 0x80 ) {
for ( fp2= (FILE *) &_fdevtab[0]; fp2; fp2 = fp2->next)
if ( (fp->_fileflag & (0x80|_FILEISDIRTY)) == (0x80|_FILEISDIRTY) )
_doflush( fp2, -1 );
}
len = read( (int)fp->_fileunit, fp->_filebufp, (int)fp->_filelen);
if ( len > 0 ) {
fp->_filecpos = fp->_filebufp;
fp->_fileend = fp->_filebufp + len;
return (*fp->_filecpos++ & 0xFF);
}
if ( len < 0 )
fp->_fileflag |= _FILEBAD;
else
fp->_fileflag |= _FILEATEOF;
return EOF;
}
int _doflush( fp, data )
FILE *fp;
int data;
{
int nchars;
char c = data;
if ( fp->_fileflag & _FILEBAD )
return EOF;
if ( fp->_fileflag & _FILEISDIRTY ) {
nchars = fp->_filecpos - fp->_filebufp;
if ( write( (int)fp->_fileunit, fp->_filebufp, nchars ) != nchars )
goto err;
}
if ( data == EOF ) {
fp->_fileflag &= ~_FILEISDIRTY;
fp->_filecpos = NULL;
fp->_fileend = NULL;
return 0;
}
if ( !fp->_filebufp )
addStreamBuf( fp );
if ( fp->_filelen == 1 ) {
if ( write( (int)fp->_fileunit, &c, 1 ) != 1 )
goto err;
return data;
}
fp->_filecpos = fp->_filebufp;
fp->_fileend = fp->_filebufp + fp->_filelen;
fp->_fileflag |= _FILEISDIRTY;
*fp->_filecpos++ = data;
return data;
err:
fp->_fileflag |= _FILEBAD;
fp->_filecpos = NULL;
fp->_fileend = NULL;
return EOF;
}